package org.custom.spring.boot.transaction.service.propagation;

import org.custom.spring.boot.transaction.entity.Transaction;
import org.custom.spring.boot.transaction.mapper.TransactionMapper;
import org.custom.spring.boot.transaction.utils.ApplicationContextHelper;
import org.custom.spring.boot.transaction.utils.ValidUtil;
import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;

/**
 * 事务传播行为为REQUIRES_NEW
 *
 * @author LiKun
 * @date 2021/9/10 15:44
 */
@Service
public class RequiresNewService {
    @Resource
    private TransactionMapper transactionMapper;

    @Transactional(propagation = REQUIRES_NEW)
    public int transaction(String data) {
        return transactionMapper.insert(Transaction.getInstance(data));
    }

    @Transactional(propagation = REQUIRES_NEW)
    public int transactionException(String data) {
        transactionMapper.insert(Transaction.getInstance(data));
        return ValidUtil.byZero();
    }

    public int withoutTransaction(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        // 因为spring事务是基于AOP(代理)实现的，因此直接调用类内部的方法REQUIRES_NEW是不会生效的
        ApplicationContextHelper.getApplication(RequiresNewService.class).withTransactionExceptionRequiresNew(data2);
        return 999;
    }

    @Transactional
    public int withTransactionWithException(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        // 因为spring事务是基于AOP(代理)实现的，因此直接调用类内部的方法REQUIRES_NEW是不会生效的
        ApplicationContextHelper.getApplication(RequiresNewService.class).withTransactionRequiresNew(data2);
        System.out.println("-----------------------------------------------------------------------------------------");
        System.out.println(transactionMapper.selectById(data2));
        System.out.println("-----------------------------------------------------------------------------------------");
        return ValidUtil.byZero();
    }

    @Transactional
    public int withTransactionCatch(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        try {
            // 因为spring事务是基于AOP(代理)实现的，因此直接调用类内部的方法REQUIRES_NEW是不会生效的
            ApplicationContextHelper.getApplication(RequiresNewService.class).withTransactionExceptionRequiresNew(data2);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return 99;
    }

    @Description("重新创建一个新的事务，类内部的直接调用会导致REQUIRES_NEW失效")
    @Transactional(rollbackFor = Exception.class, propagation = REQUIRES_NEW)
    public void withTransactionRequiresNew(String data) {
        transactionMapper.insert(Transaction.getInstance(data));
    }

    @Description("重新创建一个新的事务，类内部的直接调用会导致REQUIRES_NEW失效")
    @Transactional(rollbackFor = Exception.class, propagation = REQUIRES_NEW)
    public int withTransactionExceptionRequiresNew(String data) {
        transactionMapper.insert(Transaction.getInstance(data));
        return ValidUtil.byZero();
    }
}
